/* Copyright 2009 Requirements Management System 
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.mags.remas.view;

import java.util.ArrayList;   
import java.util.Date;
import java.util.List;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.ScrolledComposite;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.mags.common.EngineContext;
import org.mags.object.common.ParserFormatterUtils;
import org.mags.remas.control.ListValueController;
import org.mags.remas.control.ListValueInput;
import org.mags.remas.control.commons.IAction;
import org.mags.remas.model.entity.KeyDefinition;
import org.mags.remas.model.entity.provider.EnumValueProvider;
import org.mags.remas.model.entity.provider.KeyTypeProvider;
import org.mags.remas.view.commons.IChangeFocusListener;
import org.mags.remas.view.commons.ImageProvider;
import org.mags.remas.view.commons.RelationshipEditorBase;
import org.mags.remas.view.commons.ViewUtils;
import org.mags.remas.view.widgets.FieldsControl;
import org.mags.remas.view.widgets.ListValueViewer;

/**
 * 
 * @author Mario Gaitan
 *
 */
public abstract class AbstractEntityEditor extends RelationshipEditorBase 
					implements IChangeFocusListener, IAction {
	private Text txtName;
	private FieldsControl fieldsControl = new FieldsControl(this);
	private ToolItem linkButton;
	private ToolItem refreshButton;
	private ToolItem saveButton;
	private ToolItem cancelButton;
	private Label lblLink;
	private List<ListValueViewer> listViewers;
	public List<ListValueViewer> getListViewers() {
		return this.listViewers;
	}
	public Label getLblLink() {
		return lblLink;
	}
	public AbstractEntityEditor() {
		fieldsControl.setEditorPart(this);
	}
	public Text getTxtName() {
		return txtName;
	}
	public FieldsControl getFieldsControl() {
		return fieldsControl;
	}
	public ToolItem getLinkButton() {
		return linkButton;
	}
	public ToolItem getRefreshButton() {
		return refreshButton;
	}
	public ToolItem getSaveButton() {
		return saveButton;
	}
	public ToolItem getCancelButton() {
		return cancelButton;
	}
	private void createFieldControls(Composite parent) {
		listViewers = new ArrayList<ListValueViewer>();
		fieldsControl.setParent(parent);
		fieldsControl.setDisplay(super.getSite().getShell().getDisplay());
		fieldsControl.addContainer("properties", "PROPERTIES (* Required Fields)");
		fieldsControl.addReadText("properties", "property_code", "code", "");
		lblLink = fieldsControl.addReadText("properties", "property_link", "link", "");
		txtName = fieldsControl.addText("properties", "property_name", "name(*)", 255, "");
		fieldsControl.addTextArea("properties", "property_description", "Description", 510, "");
		List<KeyDefinition> keys = EngineContext.getDataContext().getEntityProviderFactory().getKeyDefinitionProvider().getByEntityTypeId(entityRelationship.getEntity().getEntityType().getEntityTypeId());
		KeyTypeProvider keyTypeProvider = EngineContext.getDataContext().getEntityProviderFactory().getKeyTypeProvider();
		EnumValueProvider enumValueProvider = EngineContext.getDataContext().getEntityProviderFactory().getEnumValueProvider();
		String label = null;
		for(KeyDefinition i: keys) {
			label = i.getName();
			if(i.getAllowEmpty().equals("N"))
				label = label + "(*)";
			if(keyTypeProvider.isENUM(i.getKeyType()))
				fieldsControl.addCombo("properties", "propertyidx_"+i.getName(), label, enumValueProvider.getByEnumNameId(i.getEnumName().getEnumNameId()), "evalue", null).setData(i);
			else if(keyTypeProvider.isLIST(i.getKeyType())) {
				ListValueViewer listValueViewer = fieldsControl.addListValue("properties", "propertyidx_"+i.getName(), label);
				listValueViewer.setCrudActions(new ListValueController(this.entityRelationship, i));
				listValueViewer.setExpandActionListener(this);
				listValueViewer.setElementImage(ImageProvider.getKeyImage(i.getListName().getName().toLowerCase()+".png"));
				listValueViewer.getControl().setData(i);
				listValueViewer.setInput(this);
				listViewers.add(listValueViewer);
			}
			else {
				if(keyTypeProvider.isDATE(i.getKeyType()))
					fieldsControl.addTextDate("properties", "propertyidx_"+i.getName(), label+" [" + ParserFormatterUtils.getInstance().getDatePattern().toLowerCase() + "]", new Date()).setData(i);
				else if(keyTypeProvider.isINTEGER(i.getKeyType()))
					fieldsControl.addText("properties", "propertyidx_"+i.getName(), label, 15, "0").setData(i);
				else if(keyTypeProvider.isFLOAT(i.getKeyType()))
					fieldsControl.addText("properties", "propertyidx_"+i.getName(), label, 15, "0").setData(i);				
				else 
					fieldsControl.addText("properties", "propertyidx_"+i.getName(), label, 255, "").setData(i);
			}
		}		
		fieldsControl.addContainer("audit", "AUDIT PROPERTIES");
		fieldsControl.addReadText("audit", "audit_createdby", "created by", "");
		fieldsControl.addReadText("audit", "audit_updatedby", "updated by", "");
		fieldsControl.addReadText("audit", "audit_creationdate", "creation date ["+ParserFormatterUtils.getInstance().getDatePattern().toLowerCase()+"]", "");
		fieldsControl.addReadText("audit", "audit_changedate", "change date ["+ParserFormatterUtils.getInstance().getDatePattern().toLowerCase()+"]", "");		
	}
	private void createToolBar(Composite parent) {
		ToolBar toolBar = new ToolBar(parent, SWT.FLAT);
		GridData gridData = new GridData();
		gridData.horizontalAlignment = SWT.RIGHT;
		gridData.grabExcessHorizontalSpace = true;		
		toolBar.setLayoutData(gridData);
		
		
		linkButton = new ToolItem(toolBar, SWT.NONE);		
		linkButton.setText("[link]");
		linkButton.setImage(ImageProvider.getCommonImage("link.png"));
		linkButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			public void widgetSelected(SelectionEvent e) {
				try {
					selectLink();
				} catch(Exception _e) {
					exceptionCatched(_e);
				}
			}
		});

		refreshButton = new ToolItem(toolBar, SWT.NONE);		
		refreshButton.setText("refresh");
		refreshButton.setImage(ImageProvider.getCommonImage("refresh.png"));
		refreshButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			public void widgetSelected(SelectionEvent e) {
				try {
					refresh();
				} catch(Exception _e) {
					exceptionCatched(_e);
				}
			}
		});

		saveButton = new ToolItem(toolBar, SWT.NONE);		
		saveButton.setText("save");
		saveButton.setImage(ImageProvider.getCommonImage("save.png"));
		saveButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			public void widgetSelected(SelectionEvent e) {
				try {
					save();
				} catch(Exception _e) {
					exceptionCatched(_e);
				}
			}
		});


		cancelButton = new ToolItem(toolBar, SWT.NONE);		
		cancelButton.setText("cancel");
		cancelButton.setImage(ImageProvider.getCommonImage("cancel.png"));
		cancelButton.addSelectionListener(new SelectionListener() {
			public void widgetDefaultSelected(SelectionEvent e) {
			}
			public void widgetSelected(SelectionEvent e) {
				try {
					cancel();
				} catch(Exception _e) {
					exceptionCatched(_e);
				}
			}
		});

	}
	public void save() {
		super.setNormalPartName();
	};
	public abstract void cancel();
	public abstract void refresh();
	public abstract void selectLink();
	@Override
	public void createPartControl(Composite parent) {
		parent.setLayout(new GridLayout(1, true));
		createToolBar(parent);
		createContent(parent);	
	}
	protected void createContent(Composite parent) {
		Composite scrlContent = new Composite(parent, SWT.BORDER);
		GridData gridData = new GridData();
		gridData.grabExcessHorizontalSpace = true;
		gridData.grabExcessVerticalSpace = true;
		gridData.horizontalAlignment = SWT.FILL;
		gridData.verticalAlignment = SWT.FILL;
		scrlContent.setLayoutData(gridData);
		scrlContent.setLayout(new FillLayout());
		ScrolledComposite scrlComposite = new ScrolledComposite(scrlContent, SWT.V_SCROLL|SWT.H_SCROLL);
		Composite content = new Composite(scrlComposite, SWT.NONE);
		content.setLayout(new GridLayout(1, true));
		createFieldControls(content);
		scrlComposite.setContent(content);
		scrlComposite.setMinSize(200, 850);
		scrlComposite.setExpandHorizontal(true);
		scrlComposite.setExpandVertical(true);		
	}
	@Override
	public boolean execute(Object object) {
		if(entityRelationship.getEntity().getEntityId()==0) throw new RuntimeException("you have to save the entity");
		ListValueViewer listViewer = (ListValueViewer)object;
		KeyDefinition keyDefinition = (KeyDefinition)listViewer.getControl().getData();
		ListValueInput listValueInput = new ListValueInput(entityRelationship, keyDefinition);
		listValueInput.setID(keyDefinition.getKeyDefinitionId());
		ViewUtils.openOrBringToTopEditor(listValueInput, ListValueEditor.ID, super.getSite());
		return true;
	}	
	@Override
	public void setFocus() {
		txtName.setFocus();
	}
	@Override
	public void doSave(IProgressMonitor monitor) {
		save();
	}
	@Override
	public void changeFocus(FocusEvent e) {
		if(super.getPartName()!=null&&!super.getPartName().startsWith("*"))
			super.setPartName("*"+super.getPartName());
	}
}
